import * as path from 'path';
import * as fs from 'fs';
import * as AdmZip from 'adm-zip';
import * as XmlJS from 'xml2js';
import * as fse from 'fs-extra';
import { BOOK_PATH } from './const'

const { parseStringPromise } = XmlJS;

// 解压文件
export function unzip(bookPath: string, unzipPath: string) {
  const zip = new AdmZip(bookPath);
    zip.extractAllTo(unzipPath, true);
}

// 解析文件
export function parseRootFile(unzipPath: string) {
  const containerPath = path.resolve(unzipPath, 'META-INF', 'container.xml');
  const containerXml = fs.readFileSync(containerPath, 'utf-8');
  // console.log("🚀 ~ parseRootFile ~ containerXml:", containerXml)
  return parseStringPromise(containerXml, { explicitArray: false }).then(result => {
    return result.container.rootfiles.rootfile['$']['full-path'];
  })
}

// 解析 opf 文件
export function parseContentOpf(unzipPath: string, opfPath: string, fileName: string) {
  // 获取opf文件路径
  const fullPath = path.resolve(unzipPath, opfPath);
  const dir = path.dirname(fullPath);
  const contentOpf = fs.readFileSync(fullPath, 'utf-8');
  return parseStringPromise(contentOpf, { explicitArray: false }).then(async (result) => {
    const { metadata, manifest } = result.package;
    console.log("🚀 ~ returnparseStringPromise ~ metadata:", metadata)
    let creator: string;
    if (metadata['dc:creator'] instanceof Array) {
      creator = metadata['dc:creator'].map(item => item._).join(',');
    } else if (metadata['dc:creator'] instanceof Object) {
      creator = metadata['dc:creator']['$']['opf:file-as'];
    } else {
      creator = metadata['dc:creator'];
    }
    let coverMeta: {};
    if (metadata.meta instanceof Array) {
      coverMeta = metadata.meta.find((meta) => meta['$']['name'] === 'cover');
    } else {
      coverMeta = metadata.meta;
    }
    const coverId = coverMeta['$']['content'];
    const coverRes = manifest.item.find((item) => item['$']['id'] === coverId);
    // const coverPath = coverRes['$']['href'].replace(/\\/g, '/'); // 封面
    const cover = path.resolve(dir, coverRes['$']['href']).replace(/\\/g, '/'); // 封面
    // console.log("🚀 ~ returnparseStringPromise ~ coverPath:", coverPath)

    const rootDir = path.dirname(opfPath)
    const content = await parseContent(dir, 'toc.ncx', rootDir, fileName);  // 解析目录
    // console.log("🚀 ~ returnparseStringPromise ~ content:", content)
    return {
      title: metadata['dc:title'],          // 书名
      language: metadata['dc:language'],    // 语言
      creator,                              // 作者
      publisher: metadata['dc:publisher'],  // 出版社
      cover,                     // 封面
      content,                              // 目录
      rootFile: opfPath,                    // 根文件
    }
  })
}

// 解析 toc.ncx 目录文件
export async function parseContent(contentDir: string, contentFilePath: string, rootDir: string, fileName: string) {
  // console.log("🚀 ~ parseContent ~ rootDir:", rootDir)
  const contentPath = path.resolve(contentDir, contentFilePath);
  const contentXml = fs.readFileSync(contentPath, 'utf-8');
  // console.log("🚀 ~ parseContent ~ contentXml:", contentXml)
  const data = await parseStringPromise(contentXml, { explicitArray: false });
  // console.log("🚀 ~ parseContent ~ data:", data)
  const navPoint = data.ncx.navMap.navPoint;
  // console.log("🚀 ~ parseContent ~ navPoint:", navPoint)
  const fileNameWithoutSuffix = fileName.replace(/\.epub$/, '');
  return navPoint.map(nav => {
    const id = nav['$']['id'];
    const playOrder = +nav['$']['playOrder'];
    const text = nav.navLabel.text;
    const href = nav.content['$']['src'];
    // console.log("🚀 ~ parseContent ~ text:", text, href)
    return {
      id,
      playOrder,
      text,
      href: `${fileNameWithoutSuffix}/${rootDir}/${href}`,
    }
  })
}

// 复制封面图片
export function copyCoverImage(bookData, tmpDir) {
  const { cover } = bookData;
  if (!cover) return;
  const coverPathName = cover.replace(tmpDir + '/', '');
  const coverDir = path.resolve(BOOK_PATH, 'cover');
  const coverNewPath = path.resolve(coverDir, coverPathName).replace(/\\/g, '/')
  // console.log("🚀 ~ copyCoverImage ~ coverPathName:", coverPathName)
  // console.log("🚀 ~ copyCoverImage ~ coverNewPath:", coverNewPath)
  fse.mkdirpSync(coverDir);
  fse.copySync(cover, coverNewPath);
  return coverPathName;
}

export function copyUnzipBook(tmpDir, dirName) {
  const bookDir = path.resolve(BOOK_PATH, 'book', dirName);
  console.log("🚀 ~ copyUnzipBook ~ bookDir:", bookDir)
  fse.mkdirpSync(bookDir);
  fse.copySync(tmpDir, bookDir);
}
